package com.gagakuai.concurrent;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/*
 * @Author houhong
 * @Description //TODO
 * <p>
 * executorService 表示 一个【执行框架】
 * 典型的实现为 线程池[ThreadPoolExecutor] 和 任务池 [ForkjoinExecutor`]
 * <p>
 * 客户端向 【执行框架】 提交任务后，由执行任务框架 进行调度，执行任务
 * 当 任务执行结束后，可以让【执行框架】 选择 停止，暂停/阻塞
 * @Date 7:41 下午 2023/2/19
 * @return {@link null}
 */
public interface ExecutorService extends Executor {
    /*
     * 运作方式同invokeAny(Collection)，不过这里限制这些操作要在指定的时间内完成，否则就抛出异常
     * 有序的关闭 [任务执行框架]，正在执行的任务不受影响
     */
    void shutdown();

    /*
     * 强制关闭所有 [任务执行框架]，包括所有的正在执行的任务，返回还未执行的任务列表
     */
    List<Runnable> shutdownNow();

    /*
     * 等待【任务执行框架】终止后，返回true
     */
    boolean awaitTermination(long timeout, TimeUnit unit);

    /*
     * 判断【任务执行框架】是否已关闭（不再接收新任务）
     */
    boolean isShutdown();

    /*
     * 判断【任务执行框架】是否已终止运行（所有任务已结束）
     */
    boolean isTerminated();

    /*
     * 包装/提交/执行 callable 类型的任务
     */
    <T> Future<T> submit(Callable<T> callable);

    /*
     * 包装/提交/执行 Runnable 类型的任务
     */
    Future<?> submit(Runnable runnable);

    /*
     * 包装/提交/执行Runnable型的任务，并预设一个返回结果
     */
    <T> Future<T> submit(Runnable runnable, T result);

    /*
     * 执行指定容器中的所有任务，返回值是所有包装后的任务列表
     */
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;

    /*
     * 在指定时间内执行指定容器中的所有任务，返回值是所有包装后的任务列表（包括超时后被中止的任务）
     */
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;

    /*
     * 从任一任务开始执行，只要发现某个任务已结束，就中断其他正在执行的任务，并返回首个被发现结束的任务的计算结果
     */
    <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException;

    /*
     * 运作方式同invokeAny(Collection)，不过这里限制这些操作要在指定的时间内完成，否则就抛出异常
     */
    <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;


}
